using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;

namespace Dimok.Web {

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>	Http. </summary>
	///
	/// <remarks>	Dimon, 12/21/2010. </remarks>
	////////////////////////////////////////////////////////////////////////////////////////////////////

	public partial class HTTP {
		private static int melisaCounter = 10;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Us. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public class US {

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>	Melissa. </summary>
			///
			/// <remarks>	Dimon, 12/21/2010. </remarks>
			////////////////////////////////////////////////////////////////////////////////////////////////////

			public class Melissa {
				public static PostalDS.StreetDataTable VerifyStreet(string zip, string address) {
					zip = NormalizeZip(zip);
					ZipType zipType = GetZipType(zip);
					WebClient wc = new WebClient();
					string url = zipType == ZipType.US ? "http://www.melissa.com/lookups/AddressVerify.asp?Address={1}&city=&state=&zip={0}" :
						"http://www.melissa.com/lookups/CanadianAddressVerify.asp?Street={1}&city=&Province=&Postcode={0}&FindAddress=Submit";
					string html =  wc.DownloadString(string.Format(url,zip,address));
					PostalDS dsPostal = new PostalDS();
					if (melisaCounter > 0)
						try {
							mshtml.HTMLDocumentClass doc = new mshtml.HTMLDocumentClass();
							mshtml.IHTMLDocument2 iHmlDoc2 = (mshtml.IHTMLDocument2)doc;
							iHmlDoc2.designMode = "On";
							iHmlDoc2.write(html);
							doc.close();
							try {
								object oElement = GetElementByText(doc, zipType== ZipType.US?"th":"td", "Address Verified");
								mshtml.HTMLTableCell cell = (mshtml.HTMLTableCell)oElement;
								cell = GetElementByText(cell.parentElement.parentElement, "td", "^Address$") as mshtml.HTMLTableCell;
								mshtml.IHTMLElementCollection kids = ((mshtml.HTMLTableCell)(cell.nextSibling)).children as mshtml.IHTMLElementCollection;
								mshtml.HTMLPhraseElement phrase = kids.item(0, 0) as mshtml.HTMLPhraseElement;
								string street = phrase.firstChild.nodeValue + "";
								string cityZipState = phrase.firstChild.nextSibling.nextSibling.firstChild.nodeValue + "";
								string zipPattern = zipType == ZipType.US ? ZIP_PATTERN_US : ZIP_PATTERN_CA;
								Match m = Regex.Match(cityZipState, @"(?<city>.+)\s+(?<state>[A-Z]{2})\s+(?<zip>"+zipPattern+")", RegexOptions.RightToLeft| RegexOptions.IgnoreCase);
								PostalDS.StreetDataTable dtStreet = dsPostal.Street;
								dtStreet.AddStreetRow("", "", "", "", street.Trim(), m.Groups["city"].Value, m.Groups["state"].Value, zip, zipType+"");
							} catch (HTMLElementNotFoundException) { }
						} catch(Exception exc) {
							melisaCounter--;
							throw;
						}
					return dsPostal.Street.Count == 0 ? EmptyStreetTable(zip,address): dsPostal.Street;
				}
				public static PostalDS StreetByZipAndHouseNumber(string zip,string houseNumber) {
					WebClient wc = new WebClient();
					string html = wc.DownloadString("http://www.melissadata.com/lookups/zipnumber.asp?Zip="+zip+"&Number="+houseNumber);
					//System.IO.File.WriteAllText("StreetByZipAndHouseNumber.htm", html);
					PostalDS dsPostal = new PostalDS();
					if (melisaCounter > 0)
						try {
							mshtml.HTMLDocumentClass doc = new mshtml.HTMLDocumentClass();
							mshtml.IHTMLDocument2 iHmlDoc2 = (mshtml.IHTMLDocument2)doc;
							iHmlDoc2.designMode = "On";
							iHmlDoc2.write(html);
							doc.close();
							foreach (mshtml.HTMLTableCell cell in Tags(doc.body, "td")) {
								if (!(cell.innerText + "").StartsWith(houseNumber+" ")) continue;
								dsPostal.Street.AddStreetRow("", "", "", houseNumber, cell.innerText.Trim(), "", "", zip, "US");
							}
							return dsPostal;
							foreach( mshtml.HTMLTable tbl in Tags(doc.body,"table") )
								if ((tbl.innerText+"").Contains(zip)) {
									PostalDS.CityRow drCity = dsPostal.City.NewCityRow();
									Match m = Regex.Match(tbl.innerText, @"\sin\s+(?<city>.+),\s+(?<state>[A-Z]{2})\s+(?<zip>[\d]+)", RegexOptions.RightToLeft);
									drCity.City = m.Groups["city"].Value;
									drCity.State = m.Groups["state"].Value;
									drCity.Country = "US";
									dsPostal.City.AddCityRow(drCity);
									PostalDS.StreetDataTable dtStreet = dsPostal.Street;
									tbl.rows.OfType<mshtml.HTMLTableRow>().Where(r => r.innerHTML.Contains("mapG.asp?zip4=" + zip))
										.Select(r => dtStreet.AddStreetRow("", "", "", houseNumber,
											r.cells.OfType<mshtml.HTMLTableCell>().First().innerText.Trim(), drCity.City, drCity.State, zip, drCity.Country))
											.ToArray();
									//for (int row = 2; true; ) {
									//  mshtml.HTMLTableRowClass tr = tbl.rows.item(row++, 0) as mshtml.HTMLTableRowClass;
									//  if (tr == null) break;
									//  string street = ((mshtml.HTMLTableCell)tr.cells.item(0,0)).innerText.Trim();
									//  dtStreet.AddStreetRow("", "", "", houseNumber, street, "", "", zip, "");
									//}
								}
						} catch {
							melisaCounter--;
							throw;
						}

					return dsPostal;
				}
			}

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>	Gets an element by text. </summary>
			///
			/// <remarks>	Dimon, 12/21/2010. </remarks>
			///
			/// <param name="doc">			The document. </param>
			/// <param name="tagName">	Name of the tag. </param>
			/// <param name="text">			The text. </param>
			///
			/// <returns>	The element by text. </returns>
			////////////////////////////////////////////////////////////////////////////////////////////////////

			public static mshtml.IHTMLElement GetElementByText(mshtml.HTMLDocument doc, string tagName, string text) {
				return GetElementByText(doc.documentElement, tagName, text);
			}

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>	Gets an element by text. </summary>
			///
			/// <remarks>	Dimon, 12/21/2010. </remarks>
			///
			/// <exception cref="Exception">										Thrown when exception. </exception>
			/// <exception cref="HTMLElementNotFoundException">	Thrown when htmlelementnotfound. </exception>
			///
			/// <param name="parent">		The parent. </param>
			/// <param name="tagName">	Name of the tag. </param>
			/// <param name="text">			The text. </param>
			///
			/// <returns>	The element by text. </returns>
			////////////////////////////////////////////////////////////////////////////////////////////////////

			public static mshtml.IHTMLElement GetElementByText(mshtml.IHTMLElement parent, string tagName, string text) {
				foreach (mshtml.IHTMLElement el in Tags(parent, tagName))
					try {
						if (el.innerText != null && Regex.IsMatch(el.innerText, text, RegexOptions.IgnoreCase))
							try {
								return GetElementByText(el, tagName, text);
							} catch (HTMLElementNotFoundException) {
								return el;
							}
					} catch (Exception exc) {
						throw new Exception("Tag <" + tagName + ">" + text + " ...</" + tagName + ">\n", exc);
					}
				throw new HTMLElementNotFoundException("Tag <" + tagName + ">" + text + " ...</" + tagName + "> not found.");
			}

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>	Street by zip and house number. </summary>
			///
			/// <remarks>	Dimon, 12/21/2010. </remarks>
			///
			/// <param name="zip">					The zip. </param>
			/// <param name="houseNumber">	The house number. </param>
			///
			/// <returns>	. </returns>
			////////////////////////////////////////////////////////////////////////////////////////////////////

			public static PostalDS StreetByZipAndHouseNumber(string zip, string houseNumber) {
				return Melissa.StreetByZipAndHouseNumber(zip, houseNumber);
			}

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>	Street by zip. </summary>
			///
			/// <remarks>	Dimon, 12/21/2010. </remarks>
			///
			/// <param name="zip">	The zip. </param>
			///
			/// <returns>	. </returns>
			////////////////////////////////////////////////////////////////////////////////////////////////////

			public static PostalDS StreetByZip(string zip) {
				string request = "http://www.melissadata.com/lookups/zipstreet.asp";// +"?InData=" + txtZip.Text;
				PostalDS dsPostal = new PostalDS();
				dsPostal.City.Merge(CitiesByZip(zip));
				return dsPostal;
				if (melisaCounter > 0)
					try {
						HttpWebRequest req = (HttpWebRequest)WebRequest.Create(request);
						req.Accept = "*/*";
						req.Headers.Add("Accept-Language", "en-us");
						req.Headers.Add("Accept-Encoding", "gzip, deflate");
						req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
						//req.Headers.Add("Host","www.melissadata.com");
						req.KeepAlive = true;
						req.Headers.Add("Cookie", "u=f=6&c=2&i=&n=&r=&d=5%2F27%2F2007&e=&l=U&s=");
						req.CookieContainer = new CookieContainer();
						//req.CookieContainer.Add(new Cookie(
						req.Timeout = 1000;
						HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
						//MessageBox.Show(new StreamReader(resp.GetResponseStream()).ReadToEnd());
						req = (HttpWebRequest)WebRequest.Create(request + "?InData=" + zip);
						req.Accept = "*/*";
						req.Headers.Add("Accept-Language", "en-us");
						req.Headers.Add("Accept-Encoding", "gzip, deflate");
						req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
						req.KeepAlive = true;
						req.Headers.Add("Cookie", resp.Cookies[0].Value);
						resp.Close();
						resp = (HttpWebResponse)req.GetResponse();
						string response = new StreamReader(resp.GetResponseStream()).ReadToEnd();
						//MessageBox.Show(response);
						PostalDS.StreetDataTable dtStreet = dsPostal.Street;
						MatchCollection mc = Regex.Matches(response, "<a.+zipstreet.asp.+?>(?<street>.+?)\\s*</a>");
						foreach (Match m in mc)
							if (m.Groups["street"].Value.Trim() != "Bookmark")
								dtStreet.AddStreetRow("", "", "", "", m.Groups["street"].Value.Trim(), "", "", "", "US");
						resp.Close();
					} catch {
						melisaCounter--;
						throw;
					}
				dsPostal.City.Merge(CitiesByZip(zip));
				return dsPostal;
			}

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>	Cities by zip. </summary>
			///
			/// <remarks>	Dimon, 12/21/2010. </remarks>
			///
			/// <param name="zip">	The zip. </param>
			///
			/// <returns>	. </returns>
			////////////////////////////////////////////////////////////////////////////////////////////////////

			public static PostalDS.CityDataTable CitiesByZip(string zip) {
				WebClient wc = new WebClient();
				string response = wc.DownloadString("http://zip4.usps.com/zip4/zcl_3_results.jsp?zip5=" + zip);
				MatchCollection mc = Regex.Matches(response, @"<(\w+)\s.+?headers=.pre.+>.+?</\1>");
				PostalDS.CityDataTable dtCity = new PostalDS.CityDataTable();
				foreach (Match m in mc) {
					XmlDocument doc = new XmlDocument();
					doc.LoadXml(m.Value);
					string city = doc.InnerText.Split(',')[0].Trim();
					string state = doc.InnerText.Split(',')[1].Trim();
					dtCity.AddCityRow(city, state, "US");
				}
				return dtCity;
			}

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>	Switch board. </summary>
			///
			/// <remarks>	Dimon, 12/21/2010. </remarks>
			///
			/// <param name="name">	The name. </param>
			/// <param name="zip">	The zip. </param>
			///
			/// <returns>	. </returns>
			////////////////////////////////////////////////////////////////////////////////////////////////////

			public static PostalDS.StreetDataTable SwitchBoard(string name, string zip) {
				string request = "http://www.switchboard.com/swbd.main/dir/wpresults.htm?MEM=20028&ypcobrand=20028&QV=&SR=&NM=" + name + "&LO=" + zip + "&search.x=0&search.y=0";
				WebClient wc = new WebClient();
				string responce = wc.DownloadString(request);
				MatchCollection mc = Regex.Matches(responce, @"<a class=.name.[^>]+>(?<name>[^<]+).+?<(span)[^>]+?contactinfo[^>]+?>(?<info>([\s\S]*?)citystatezip([\s\S]*?)</\1>)");
				PostalDS.StreetDataTable dtPerson = new PostalDS().Street;
				foreach (Match m in mc) {
					List<string> alFields = new List<string>();
					//dtPerson.Rows.Add
					Regex regex = new Regex(@"<(span)[^>]*>(?<info>[\s\S]+?)</\1>", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
					MatchCollection mcInfo = regex.Matches(m.Groups["info"].Value);
					alFields.Add(m.Groups["name"].Value);
					foreach (Match mInfo in mcInfo)
						alFields.Add(mInfo.Groups["info"].Value.Replace("&nbsp;|&nbsp;", "").Trim());
					Match mCSZ = Regex.Match(alFields[alFields.Count - 1] + "", @"(?<city>.+)\s*,\s*(?<state>\w\w)\s+(?<zip>.+)");
					alFields.RemoveAt(alFields.Count - 1);
					alFields.Add(mCSZ.Groups["city"].Value);
					alFields.Add(mCSZ.Groups["zip"].Value);
					alFields.Add(mCSZ.Groups["state"].Value);
					dtPerson.AddStreetRow(alFields[0], "", alFields[1], "", alFields[2], alFields[3], alFields[4], alFields[5], "US");
				}
				return dtPerson;
			}

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>	White pages. </summary>
			///
			/// <remarks>	Dimon, 12/21/2010. </remarks>
			///
			/// <param name="firstName">	Name of the first. </param>
			/// <param name="lastName">		Name of the last. </param>
			/// <param name="zip">				The zip. </param>
			///
			/// <returns>	. </returns>
			////////////////////////////////////////////////////////////////////////////////////////////////////

			public static Dimok.Web.PostalDS.StreetDataTable WhitePages(string firstName, string lastName, string zip) {
				string query = "/resi_qry_results.pl?fid=n&fk=eq&f=" + firstName + "&lk=eq&l=" + lastName + "&c=" + zip + "&s=";
				string url = "http://www.whitepages.com" + query;
				HttpWebRequest wrq = (HttpWebRequest)WebRequest.Create(url);
				HttpWebResponse wrp = null;
				Dimok.Web.PostalDS.StreetDataTable dtStreet = new Dimok.Web.PostalDS().Street;
				try {
					wrp = (HttpWebResponse)wrq.GetResponse();
				} catch {
					return dtStreet;
				}
				StreamReader sr = new StreamReader(wrp.GetResponseStream());
				string text = sr.ReadToEnd();
				wrp.Close();
				//System.Windows.Forms.WebBrowser wb = new System.Windows.Forms.WebBrowser();
				//wb.Navigate("about:blank");
				//wb.DocumentText = text;
				mshtml.HTMLDocumentClass doc = new mshtml.HTMLDocumentClass();
				mshtml.IHTMLDocument2 iHmlDoc2 = (mshtml.IHTMLDocument2)doc;
				iHmlDoc2.designMode = "On";
				iHmlDoc2.write(text);
				doc.close();
				Dimok.Web.PostalDS.StreetRow rowStreet = dtStreet.NewStreetRow();
				mshtml.IHTMLElement listing = doc.getElementById("results_single_listing") as mshtml.IHTMLElement;
				if (listing == null)
					listing = doc.getElementById("results_multiple_listing_container_1") as mshtml.IHTMLElement;
				if (listing == null) return dtStreet;
				mshtml.IHTMLElementCollection listingAll = (mshtml.IHTMLElementCollection)listing.all;
				mshtml.IHTMLElementCollection tags = listingAll.tags("h3") as mshtml.IHTMLElementCollection;
				if (tags.length == 0) return dtStreet;
				//((mshtml.IHTMLElement)((mshtml.IHTMLElementCollection)((mshtml.IHTMLElementCollection)doc.getElementById("results_single_listing").all).tags("h3")).item(0,null)).innerHTML
				mshtml.IHTMLElement el = tags.item(0, null) as mshtml.IHTMLElement;
				if (el == null) return dtStreet;
				dtStreet.AddStreetRow(rowStreet);
				rowStreet.LastName = el.innerText.Split(',')[0].Trim();
				rowStreet.FirstName = el.innerText.Split(',')[1].Trim();
				tags = listingAll.tags("p") as mshtml.IHTMLElementCollection;
				if (tags.length >= 3) {
					int l = tags.length - 2;
					el = tags.item(l - 2, null) as mshtml.IHTMLElement;
					rowStreet.Street = el.innerText;
					el = tags.item(l - 1, null) as mshtml.IHTMLElement;
					rowStreet.City = el.innerText.Split(',')[0];
					rowStreet.State = Regex.Split(el.innerText, ",\\s+")[1].Split(' ')[0];
					rowStreet.Zip = Regex.Split(el.innerText, ",\\s+")[1].Split(' ')[1];
					el = tags.item(l, null) as mshtml.IHTMLElement;
					rowStreet.PersonPhone = Regex.Replace(el.innerText, "\\D", "");
				}
				rowStreet.Country = "US";
				return dtStreet;
			}

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>	White pages. </summary>
			///
			/// <remarks>	Dimon, 12/21/2010. </remarks>
			///
			/// <exception cref="MalformedPhoneException">	Thrown when malformedphone. </exception>
			///
			/// <param name="phone">	The phone. </param>
			///
			/// <returns>	. </returns>
			////////////////////////////////////////////////////////////////////////////////////////////////////

			public static Dimok.Web.PostalDS.StreetDataTable WhitePages(string phone) {
				if (phone == "") throw new MalformedPhoneException();
				string query = "/search/ReversePhone?full_phone=" + phone + "&localtime=survey";
				HttpWebRequest wrq = (HttpWebRequest)WebRequest.Create("http://www.whitepages.com" + query);
				HttpWebResponse wrp = (HttpWebResponse)wrq.GetResponse();
				StreamReader sr = new StreamReader(wrp.GetResponseStream());
				string text = sr.ReadToEnd();
				wrp.Close();
				//System.Windows.Forms.WebBrowser wb = new System.Windows.Forms.WebBrowser();
				//wb.Navigate("about:blank");
				//wb.DocumentText = text;
				mshtml.HTMLDocumentClass doc = new mshtml.HTMLDocumentClass();
				mshtml.IHTMLDocument2 iHmlDoc2 = (mshtml.IHTMLDocument2)doc;
				iHmlDoc2.designMode = "On";
				iHmlDoc2.write(text);
				doc.close();
				Dimok.Web.PostalDS.StreetDataTable dtStreet = new Dimok.Web.PostalDS().Street;
				Dimok.Web.PostalDS.StreetRow rowStreet = dtStreet.NewStreetRow();
				mshtml.IHTMLElement listing = doc.getElementById("results_single_listing") as mshtml.IHTMLElement;
				if (listing == null) {
					listing = doc.getElementById("results_multiple_listing_container_1") as mshtml.IHTMLElement;
					if (listing == null) return dtStreet;
					listing = Tag(listing, "DD");
					if (listing == null) return dtStreet;
				}
				mshtml.IHTMLElementCollection listingAll = (mshtml.IHTMLElementCollection)listing.all;
				mshtml.IHTMLElementCollection tags = listingAll.tags("h3") as mshtml.IHTMLElementCollection;
				if (tags.length == 0) return dtStreet;
				//((mshtml.IHTMLElement)((mshtml.IHTMLElementCollection)((mshtml.IHTMLElementCollection)doc.getElementById("results_single_listing").all).tags("h3")).item(0,null)).innerHTML
				mshtml.IHTMLElement el = tags.item(0, null) as mshtml.IHTMLElement;
				if (el == null) return dtStreet;
				dtStreet.AddStreetRow(rowStreet);
				rowStreet.LastName = el.innerText.Split(',')[0].Trim();
				rowStreet.FirstName = el.innerText.Split(',')[1].Trim();
				tags = listingAll.tags("p") as mshtml.IHTMLElementCollection;
				if (tags.length >= 3) {
					int l = tags.length - 2;
					el = tags.item(l - 2, null) as mshtml.IHTMLElement;
					rowStreet.Street = el.innerText;
					el = tags.item(l - 1, null) as mshtml.IHTMLElement;
					rowStreet.City = el.innerText.Split(',')[0];
					rowStreet.State = Regex.Split(el.innerText, ",\\s+")[1].Split(' ')[0];
					rowStreet.Zip = Regex.Split(el.innerText, ",\\s+")[1].Split(' ')[1];
					el = tags.item(l, null) as mshtml.IHTMLElement;
					rowStreet.PersonPhone = NormalizePhone(el.innerText);
				}
				rowStreet.Country = "US";
				return dtStreet;
			}
			private static int GoogleErrorCount = 10;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>	Googles. </summary>
			///
			/// <remarks>	Dimon, 12/21/2010. </remarks>
			///
			/// <param name="phone">	The phone. </param>
			///
			/// <returns>	. </returns>
			////////////////////////////////////////////////////////////////////////////////////////////////////

			public static Dimok.Web.PostalDS.StreetDataTable Google(string phone) {
				Dimok.Web.PostalDS.StreetDataTable dtStreet = new Dimok.Web.PostalDS().Street;
				if (GoogleErrorCount == 0) return dtStreet;
				try {
					WebClient wc = new WebClient();
					string html = wc.DownloadString("http://www.google.com/search?q=" + phone + "&hl=en&pb=r");
					mshtml.HTMLDocumentClass doc = new mshtml.HTMLDocumentClass();
					mshtml.IHTMLDocument2 iHmlDoc2 = (mshtml.IHTMLDocument2)doc;
					iHmlDoc2.designMode = "On";
					iHmlDoc2.write(html);
					doc.close();
					mshtml.HTMLTableCell td = doc.getElementById("mr") as mshtml.HTMLTableCell;
					if (td != null) {
						Dimok.Web.PostalDS.StreetRow drStreet = dtStreet.NewStreetRow();
						mshtml.HTMLTableRowClass tr = td.parentElement as mshtml.HTMLTableRowClass;
						string firstLastName = ((mshtml.IHTMLElement)tr.cells.item(0, 0)).innerText;
						Match m = Regex.Match(firstLastName, @"(?<fn>.+)\s+(?<ln>[^\s]+)$", RegexOptions.RightToLeft);
						drStreet.LastName = m.Groups["ln"].Value;
						drStreet.FirstName = m.Groups["fn"].Value;
						string address = ((mshtml.IHTMLElement)tr.cells.item(2, 0)).innerText;
						m = Regex.Match(address, @"(?<street>.+),\s*(?<city>[^\s]+),\s*(?<state>[^\s]+)\s+(?<zip>[^\s]+)$", RegexOptions.RightToLeft);
						drStreet.Street = m.Groups["street"].Value;
						drStreet.City = m.Groups["city"].Value;
						drStreet.Zip = m.Groups["zip"].Value;
						drStreet.State = m.Groups["state"].Value;
						drStreet.Country = "US";
						dtStreet.AddStreetRow(drStreet);
					}
				} catch {
					GoogleErrorCount--;
					throw;
				}
				return dtStreet;
			}

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>	Tags. </summary>
			///
			/// <remarks>	Dimon, 12/21/2010. </remarks>
			///
			/// <param name="el">				The el. </param>
			/// <param name="tagName">	Name of the tag. </param>
			///
			/// <returns>	. </returns>
			////////////////////////////////////////////////////////////////////////////////////////////////////

			private static mshtml.IHTMLElementCollection Tags(mshtml.IHTMLElement el, string tagName) {
				mshtml.IHTMLElementCollection all = (mshtml.IHTMLElementCollection)el.all;
				return all.tags(tagName) as mshtml.IHTMLElementCollection;
			}

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>	Tags. </summary>
			///
			/// <remarks>	Dimon, 12/21/2010. </remarks>
			///
			/// <param name="el">				The el. </param>
			/// <param name="tagName">	Name of the tag. </param>
			///
			/// <returns>	. </returns>
			////////////////////////////////////////////////////////////////////////////////////////////////////

			private static mshtml.IHTMLElement Tag(mshtml.IHTMLElement el, string tagName) {
				mshtml.IHTMLElementCollection tags = Tags(el, tagName);
				return tags.length == 0 ? (mshtml.IHTMLElement)null : tags.item(0, 0) as mshtml.IHTMLElement;
			}

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// <summary>	Searches for the first phones. </summary>
			///
			/// <remarks>	Dimon, 12/21/2010. </remarks>
			///
			/// <param name="firstName">	Name of the first. </param>
			/// <param name="lastName">		Name of the last. </param>
			/// <param name="zip">				The zip. </param>
			///
			/// <returns>	The found phones. </returns>
			////////////////////////////////////////////////////////////////////////////////////////////////////

			public static string[] FindPhones(string firstName, string lastName, string zip) {
				string query = "/resi_qry_results.pl?fid=n&fk=eq&f=" + firstName + "&lk=eq&l=" + lastName + "&c=" + zip + "&s=";
				HttpWebRequest wrq = (HttpWebRequest)WebRequest.Create("http://www.whitepages.com" + query);
				HttpWebResponse wrp = (HttpWebResponse)wrq.GetResponse();
				StreamReader sr = new StreamReader(wrp.GetResponseStream());
				string text = sr.ReadToEnd();
				wrp.Close();
				mshtml.HTMLDocumentClass doc = new mshtml.HTMLDocumentClass();
				doc.close();
				doc.open("about:blank", null, null, null);
				doc.write(text);
				//string sRe = @"<table(?:.|\n)+?"+lastName+@"(?:.|\n)+?"+firstName+@"(?:.|\n)+?\(\d\d\d\)\s+\d\d\d-\d\d\d\d(?:.|\n)+?table>";
				string sRe = zip + @"[\s\S]{1,20}?\d\d\d-\d\d\d\d";
				MatchCollection mcTable = Regex.Matches(text, sRe, RegexOptions.IgnoreCase | RegexOptions.Compiled);
				List<string> scPhones = new List<string>();
				foreach (Match m in mcTable) {
					string phone = Regex.Match(m.Value, @"\(\d\d\d\)\s+\d\d\d-\d\d\d\d", RegexOptions.Compiled).Value;
					if (!scPhones.Contains(phone))
						scPhones.Add(phone);
				}
				return scPhones.ToArray();
			}
		}
	}
}
